package com.skcc.cop.mrtaxi.biz;


import java.util.ArrayList;
import java.util.List;

import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.skcc.cop.mrtaxi.BaseActivity;
import com.skcc.cop.mrtaxi.R;
import com.skcc.cop.mrtaxi.biz.appinfo.AppInfoActivity;
import com.skcc.cop.mrtaxi.biz.destination.ManageDestinationActivity;
import com.skcc.cop.mrtaxi.biz.faq.FaqActivity;
import com.skcc.cop.mrtaxi.biz.history.CallHistoryActivity;
import com.skcc.cop.mrtaxi.http.GetDriverListListener;
import com.skcc.cop.mrtaxi.http.model.Driver;
import com.skcc.cop.mrtaxi.util.Dialogs;
import com.skcc.cop.mrtaxi.util.Dialogs.DialogListener;
import com.skcc.cop.mrtaxi.util.LocationUtils;
import com.skcc.cop.mrtaxi.util.LogControl;
import com.skcc.cop.mrtaxi.view.TitleBar3;
import com.skcc.cop.mrtaxi.view.TitleBar3.OnTitleBarEventListener3;


/**
 * 
 * @author project team
 * 
 */
public class HomeMapActivity extends BaseActivity implements
	OnTitleBarEventListener3,
	GooglePlayServicesClient.ConnectionCallbacks,
	GooglePlayServicesClient.OnConnectionFailedListener{

	// ===========================================================
	// Constants
	// ===========================================================
	private static final String TAG = HomeMapActivity.class.getSimpleName();
	 
	private final int MAP_TYPE = GoogleMap.MAP_TYPE_NORMAL;
	 
	 
	// ===========================================================
	// Fields
	// ===========================================================
//	private Button mOpenDestinationButton;
//	private Button mOpenDriverListButton;
	private Spinner mOpenSelectDistanceSpinner;
	private ArrayAdapter<CharSequence> adapter;
	private DrawerLayout mDrawerLayout;
	private View mMenu;
	
	// TODO: ImageView 로 변경할 것.
	private TextView mDestinationTextview;
	private TextView mCallhistoryTextview;
	private TextView mFaqTextview;
	private TextView mAppinfoTextview;
	 
	private TitleBar3 mTitleBarView;
	 
	// Stores the current instantiation of the location client in this object
	private LocationClient mLocationClient;
 
	private GoogleMap googleMap;
	private float cameraZoom;
	private int distanceId;
 
	// private AdView adView;

 
    // ===========================================================
    // Methods for/from SuperClass/Interfaces
    // ===========================================================
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_home_map);
  
		mTitleBarView = (TitleBar3) this.findViewById(R.id.titlebar_view);
		mTitleBarView.setEventListener(this);
		mTitleBarView.showMenu();
		mTitleBarView.showMoveList();
		mTitleBarView.setTitle(R.string.title);
  
//		mOpenDestinationButton = (Button)this.findViewById(R.id.home_opendestination_button);
//		mOpenDriverListButton = (Button)this.findViewById(R.id.home_opendriverlist_button);
		mOpenSelectDistanceSpinner = (Spinner)this.findViewById(R.id.home_selectdistance_spinner);
  
		adapter = ArrayAdapter.createFromResource(this, 
				R.array.taxi_distance_array, android.R.layout.simple_spinner_dropdown_item);
  
//		mOpenDestinationButton.setOnClickListener(clickListener);
//		mOpenDriverListButton.setOnClickListener(clickListener);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		mOpenSelectDistanceSpinner.setAdapter(adapter);
  
		mDrawerLayout = (DrawerLayout) this.findViewById(R.id.drawer_layout);
		mDrawerLayout.setDrawerListener(new AppDrawerListener());
		mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
		
		mMenu = this.findViewById(R.id.home_menu_layout);
		mDestinationTextview = (TextView) this.findViewById(R.id.menu_destination_textview);
		mCallhistoryTextview = (TextView) this.findViewById(R.id.menu_callhistory_textview);
		mFaqTextview = (TextView) this.findViewById(R.id.menu_faq_textview);
		mAppinfoTextview = (TextView) this.findViewById(R.id.menu_appinfo_textview);
		
		mMenu.setOnClickListener(clickListener);
		mDestinationTextview.setOnClickListener(clickListener);
		mCallhistoryTextview.setOnClickListener(clickListener);
		mFaqTextview.setOnClickListener(clickListener);
		mAppinfoTextview.setOnClickListener(clickListener);
  
		mOpenSelectDistanceSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// TODO Auto-generated method stub
				String[] methods = getResources().getStringArray(R.array.taxi_distance_array);
    
				if(id == 0) {
					distanceId = 0;
					getTaxiDriverList(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude());
					Toast.makeText(HomeMapActivity.this, methods[position] + " 선택", Toast.LENGTH_LONG).show();
				} else if(id == 1) {
					distanceId = 1;
					getTaxiDriverList(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude(), 1);
					Toast.makeText(HomeMapActivity.this, methods[position] + " 선택", Toast.LENGTH_LONG).show();
				} else if(id == 2) {
					distanceId = 2;
					getTaxiDriverList(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude(), 3);
					Toast.makeText(HomeMapActivity.this, methods[position] + " 선택", Toast.LENGTH_LONG).show();
				} else if (id == 3) {
					distanceId = 3;
					getTaxiDriverList(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude(), 5);
					Toast.makeText(HomeMapActivity.this, methods[position] + " 선택", Toast.LENGTH_LONG).show();
				} else {
					distanceId = 4;
					getTaxiDriverList(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude(), 10);
					Toast.makeText(HomeMapActivity.this, methods[position] + " 선택", Toast.LENGTH_LONG).show();
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				// TODO Auto-generated method stub
    
			}
		});
  
		SupportMapFragment mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
		googleMap = mapFrag.getMap();
  
		googleMap.setMapType(MAP_TYPE);
		googleMap.getUiSettings().setCompassEnabled(true);
		googleMap.getUiSettings().setZoomControlsEnabled(true);
		googleMap.getUiSettings().setMyLocationButtonEnabled(true);
  
		// 확대/축소 비율을 설정한다.
		cameraZoom = 15;
  
		// Create a new location client, using the enclosing class to handle callbacks.
        	mLocationClient = new LocationClient(this, this, this);
	}
 
	// Called when the Activity becomes visible.
    	@Override
    	protected void onStart() {
    		super.onStart();
    		LogControl.d(TAG, " in onStart >>>>>");
        
    		// Connect the client.
    		mLocationClient.connect();
    	}

    	@Override
    	protected void onResume() {
    		super.onResume();
    		LogControl.d(TAG, " in onResume >>>>>");
  
    	}

    	@Override
    	protected void onPause() {
    		super.onPause();
    		LogControl.d(TAG, " in onPause >>>>>");
    	}
 
    	// Called when the Activity is no longer visible.
    	@Override
    	protected void onStop() {
    		LogControl.d(TAG, " in onStop >>>>>");
     
    		// Disconnecting the client invalidates it.
    		mLocationClient.disconnect();
        
    		super.onStop();
    	}

    	@Override
    	protected void onDestroy() {
    		// application.resetResource();
    		LogControl.d(TAG, " in onDestroy >>>>>");
    		super.onDestroy();
    	}

    	@Override
    	public void onBackPressed() {
    		Intent intent = new Intent(HomeMapActivity.this, HomeListActivity.class);
    		intent.putExtra("distance", distanceId);
    		startActivity(intent);
    		finish();
    	}
 
    	@Override
    	public void onConnectionFailed(ConnectionResult connectionResult) {
    		/*
    		 * Google Play services can resolve some errors it detects.
    		 * If the error has a resolution, try sending an Intent to
    		 * start a Google Play services activity that can resolve
    		 * error.
    		 */
    		if (connectionResult.hasResolution()) {
    			try {

    				// Start an Activity that tries to resolve the error
    				connectionResult.startResolutionForResult(
    						this,
    						LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);

    				/*
    				 * Thrown if Google Play services canceled the original PendingIntent
    				 */

    			} catch (IntentSender.SendIntentException e) {

    				// Log the error
    				e.printStackTrace();
    			}
    		} else {

    			// If no resolution is available, display a dialog to the user with the error.
    			showErrorDialog(connectionResult.getErrorCode());
    		}
    	}

    	@Override
    	public void onConnected(Bundle arg0) {
    		if (servicesConnected()) {
    			// Get the current location
    			Location currentLocation = mLocationClient.getLastLocation();
            
    			if(currentLocation == null){
    				Dialogs.showDialog(HomeMapActivity.this, getString(R.string.no_network), dialogListener3);
    			}else{
    				getTaxiDriverList(currentLocation.getLatitude(), currentLocation.getLongitude());
    			}    
    		}
    	}

    	@Override
    	public void onDisconnected() {
    		// TODO Auto-generated method stub
  
    	}
    	
    	// ===========================================================
    	// Methods
    	// ===========================================================
    	private OnClickListener clickListener = new OnClickListener() {
    		
    		@Override
    		public void onClick(View v) {
    			if(v.getId() == R.id.menu_destination_textview) {
    				Log.i(TAG, ">>>>>>>>>>>> menu_destination_textview");
    				moveManageDestination();
    			} else if(v.getId() == R.id.menu_callhistory_textview) {
    				Intent intent = new Intent(HomeMapActivity.this, CallHistoryActivity.class);
    		        startActivity(intent);
    			} else if(v.getId() == R.id.menu_faq_textview) {
    				Intent intentFaq = new Intent(HomeMapActivity.this, FaqActivity.class);
    		        startActivity(intentFaq);
    			} else if(v.getId() == R.id.menu_appinfo_textview) {
    				Intent intentAppInfo = new Intent(HomeMapActivity.this, AppInfoActivity.class);
    		        startActivity(intentAppInfo);
    			} /*else if(v.getId() == R.id.home_opendestination_button) {
    				Log.i(TAG, ">>>>>>>>>>>> openConfig_button");
    				moveManageDestination();
    			} */
    			
    			return;
    		}
    	};
 
 
    	// ===========================================================
    	// Methods
    	// ===========================================================
    	private void getTaxiDriverList(final double latitude, final double longitude) {
    		showProgressDialog(this, R.string.loading);
  
    		gateway.getTaxiDriverList(latitude, longitude, new GetDriverListListener() {

    			@Override
    			public void onNoNetwork() {
    				dismissProgressDialog();
    
    				Dialogs.showDialog(HomeMapActivity.this, getString(R.string.no_network), dialogListener3);
    			}

    			@Override
    			public void onNoResponse() {
    				dismissProgressDialog();
    
    				Dialogs.showDialog(HomeMapActivity.this, getString(R.string.no_respond), dialogListener3);
    			}

    			@Override
    			public void onSessionTimeOut() {
    				dismissProgressDialog();
    
    				Dialogs.showDialog(HomeMapActivity.this, getString(R.string.session_timeout), dialogListener3);
    			}

    			@Override
    			public void onSuccess(List<Driver> drivers) {
    				dismissProgressDialog();
    
    				showDriverOnMap(drivers);
    
    				setCenterLocation(latitude, longitude);
    			}

    			@Override
    			public void onFail(int code, String msg) {
    				dismissProgressDialog();
    
    				Dialogs.showDialog(HomeMapActivity.this, getString(R.string.server_message) + msg, dialogListener3);
    			}
    		});
    	}
 
    	// ===========================================================
    	// Methods (Overloading)
    	// ===========================================================
    	private void getTaxiDriverList(final double latitude, final double longitude, final int distance) {
    		showProgressDialog(this, R.string.loading);
  
    		gateway.getTaxiDriverList(latitude, longitude, new GetDriverListListener() {

    			@Override
    			public void onNoNetwork() {
    				dismissProgressDialog();
    
    				Dialogs.showDialog(HomeMapActivity.this, getString(R.string.no_network), dialogListener3);
    			}

    			@Override
    			public void onNoResponse() {
    				dismissProgressDialog();
    
    				Dialogs.showDialog(HomeMapActivity.this, getString(R.string.no_respond), dialogListener3);
    			}

    			@Override
    			public void onSessionTimeOut() {
    				dismissProgressDialog();
    
    				Dialogs.showDialog(HomeMapActivity.this, getString(R.string.session_timeout), dialogListener3);
    			}

    			@Override
    			public void onSuccess(List<Driver> drivers) {
    				dismissProgressDialog();
    
    				final int size = drivers.size();
    				final List<Driver> driverInDistance = new ArrayList<Driver> (size);
    
//    				System.out.println(distance);
    				for(int i = 0; i < drivers.size(); i++) {
    					Driver driver = drivers.get(i);
    					double driverLatitude = driver.getLatitude();
    					double driverLongitude = driver.getLongitude();
//     					System.out.println(Math.abs(distance(latitude, longitude, driverLatitude, driverLongitude)));
    
    					if(Math.abs(distance(latitude, longitude, driverLatitude, driverLongitude)) < distance) {
    						driverInDistance.add(driver);
    					}
    				}
    
    				showDriverOnMap(driverInDistance);
    
    				setCenterLocation(latitude, longitude);
    			}

    			@Override
    			public void onFail(int code, String msg) {
    				dismissProgressDialog();
    
    				Dialogs.showDialog(HomeMapActivity.this, getString(R.string.server_message) + msg, dialogListener3);
    			}
    		});
    	}
 
    	/**
    	 * 현재 자신의 위치를 중심으로 한다.
    	 * @param latitude
    	 * @param longitude
    	 */
    	protected void setCenterLocation(double latitude, double longitude) {
    		LatLng cameraLatLng = new LatLng(latitude, longitude);
    		googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(cameraLatLng, cameraZoom));
  
    		googleMap.addMarker(new MarkerOptions().position(cameraLatLng)
    				.icon(BitmapDescriptorFactory.fromResource(R.drawable.current_icon)));
    	}

    	private void showDriverOnMap(final List<Driver> drivers) {
    		// clear "all markers, overlays, and polylines from the map"
    		googleMap.clear();
  
    		final int size = drivers.size();
    		final List<Marker> markerList = new ArrayList<Marker> (size);
  
    		for(int i = 0; i < size; i++) {
    			Driver driver = drivers.get(i);

    			LatLng latLng = new LatLng(driver.getLatitude(), driver.getLongitude());
    			Marker marker = googleMap.addMarker(new MarkerOptions().position(latLng)
    					.icon(BitmapDescriptorFactory.fromResource(R.drawable.taxt_icon)));
   
    			markerList.add(marker);
    		}
  
    		googleMap.setOnMarkerClickListener(new OnMarkerClickListener() {

    			@Override
    			public boolean onMarkerClick(Marker marker) {
    				for (int i=0; i<size; i++) {
    					Marker item = markerList.get(i);
    					if (marker.getId().equals(item.getId())) {
    						Driver d = drivers.get(i);
//      					Dialogs.showDialogDriverInfo(HomeMapActivity.this, d, dialogListener2);
    						Intent intent = new Intent(HomeMapActivity.this, CallRequestActivity.class);
    						Bundle bundle = new Bundle();
    						Location currentLocation = mLocationClient.getLastLocation();
    						double userLatitude = currentLocation.getLatitude();
    						double userLongitude = currentLocation.getLongitude();
    						bundle.putString("imgUrl", d.getImgUrl());
    						bundle.putString("driverName", d.getName());
    						bundle.putString("carNumber", d.getCarNumber());
    						bundle.putString("companyName", d.getCompany());
    						bundle.putString("driverPhoneNumber",d.getPhoneNumber());
    						bundle.putDouble("userLatitude", userLatitude);
    						bundle.putDouble("userLongitude", userLongitude);
    						bundle.putInt("distance", d.getDistance());
    						intent.putExtra("driver", bundle);

    						SharedPreferences.Editor editor = getSharedPreferences("driverSharedPref",MODE_PRIVATE).edit();
    						editor.putString("imgUrl", d.getImgUrl());
    						editor.putString("driverName", d.getName());
    						editor.putString("carNumber", d.getCarNumber());
    						editor.putString("companyName", d.getCompany());
    						editor.putString("driverPhoneNumber", d.getPhoneNumber());
    						editor.putFloat("userLatitude", (float)userLatitude);
    						editor.putFloat("userLongitude", (float)userLongitude);
    						editor.putFloat("distance", d.getDistance());
    						editor.commit();
    						startActivity(intent);
    						break;
    					}
    				}
    				return false;
    			}
   
    		});
    	}
 
//    	private OnClickListener clickListener = new OnClickListener() {
//  
//    		@Override
//    		public void onClick(View v) {
//    			if(v.getId() == R.id.home_opendestination_button) {
//    				Log.i(TAG, ">>>>>>>>>>>> openConfig_button");
//    
//    				Intent intent = new Intent(HomeMapActivity.this, ManageDestinationActivity.class);
//    				startActivity(intent);
//    			} else if(v.getId() == R.id.home_opendriverlist_button) {
//    				Log.i(TAG, ">>>>>>>>>>>> openDriverList_button");
//
//    				Intent intent = new Intent(HomeMapActivity.this, HomeListActivity.class);
//    				intent.putExtra("distance", distanceId);
//    				startActivity(intent);
//    				finish();
//    			}
//    			return;
//    		}
//    	};
 
 
// 	// TODO: 콜 요청 전문 보내기
// 	// 1. 선택된 목적지 정보를 보내야 한다.
// 	// 2. 고객 정보를 보내야 한다.
// 	// 3. 인터페이스 문서보고 메소드 명/전문명 수정할 것.
// 	private void requestCall() {
//  showProgressDialog(this, R.string.loading);
//  
//  String tempDriverId = "TempDriverId";
//  String tempUserId = "TempUserId";
////  gateway.call(tempDriverId, tempUserId, new CallListener() {
////
////   @Override
////   public void onNoNetwork() {
////    dismissProgressDialog();
////    
////    Dialogs.showDialog(HomeMapActivity.this, getString(R.string.no_network), dialogListener);
////   }
////
////   @Override
////   public void onNoResponse() {
////    dismissProgressDialog();
////    
////    Dialogs.showDialog(HomeMapActivity.this, getString(R.string.no_respond), dialogListener);
////   }
////
////   @Override
////   public void onSessionTimeOut() {
////    dismissProgressDialog();
////    
////    Dialogs.showDialog(HomeMapActivity.this, getString(R.string.session_timeout), dialogListener);
////   }
////
////   @Override
////   public void onSuccess() {
////    dismissProgressDialog();
////    
////    Toast.makeText(HomeMapActivity.this, getString(R.string.call_success), Toast.LENGTH_LONG).show();
////   }
////
////   @Override
////   public void onFail(int code, String msg) {
////    dismissProgressDialog();
////    
////    Dialogs.showDialog(HomeMapActivity.this, getString(R.string.server_message) + msg, dialogListener);
////   }
////  });
// }
 
    	// ===========================================================
    	// Inner and Anonymous Classes
    	// ===========================================================
    	private class AppDrawerListener implements DrawerLayout.DrawerListener {

    		@Override
    		public void onDrawerOpened(View drawerView) {
//    			mOpenedDrawer = true;
    		}

    		@Override
    		public void onDrawerClosed(View drawerView) {
//    			mOpenedDrawer = false;
    		}

    		@Override
    		public void onDrawerSlide(View drawerView, float slideOffset) {
    		}

    		@Override
    		public void onDrawerStateChanged(int newState) {
    		}
    	}
 
    	// ===========================================================
    	// Inner and Anonymous Classes
    	// ===========================================================
    	private DialogListener dialogListener = new DialogListener() {

    		@Override
    		public void onClickedOk() {
    			Dialogs.dismiss();
    		}

    		@Override
    		public void onClickedCancel() {
    			Dialogs.dismiss();
    		}
    	};
 
 
// private DialogListener dialogListener2 = new DialogListener() {
//
//  @Override
//  public void onClickedOk() {
//   Dialogs.dismiss();
//   
//   requestCall();
//  }
//
//  @Override
//  public void onClickedCancel() {
//   Dialogs.dismiss();
//  }
// };
 
    	private DialogListener dialogListener3 = new DialogListener() {

    		@Override
    		public void onClickedOk() {
    			Dialogs.dismiss();
   
    			finish();
    		}

    		@Override
    		public void onClickedCancel() {
    			// TODO Auto-generated method stub
    		}
    	};
 
    	public double distance(double lat1, double lon1, double lat2, double lon2) { 
    		double theta, dist; 
    		theta = lon1 - lon2; 
    		dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta)); 
    		dist = Math.acos(dist); 
    		dist = rad2deg(dist); 
    		dist = dist * 60 * 1.1515; // statute miles. 단위는 기본 마일. 
    		dist = dist * 1.609344; 
    		return dist;
    	}
 
    	// 주어진 도(degree) 값을 라디언으로 변환
    	private double deg2rad(double deg) { 
    		return (double)(deg * Math.PI / (double)180d);
    	}
 
    	// 주어진 라디언(radian) 값을 도(degree) 값으로 변환
    	private double rad2deg(double rad) { 
    		return (double)(rad * (double)180d / Math.PI);
    	}

    	@Override
    	public void onMenuClicked() {
    		// TODO Auto-generated method stub
    		openDrawer();
    	}
 
    	private void openDrawer() {
    		mDrawerLayout.openDrawer(Gravity.LEFT);
    	}
    	
    	private void moveManageDestination() {
    		Intent intent = new Intent(HomeMapActivity.this, ManageDestinationActivity.class);
            startActivity(intent);
    	}

    	@Override
    	public void onMoveListClicked() {
    		// TODO Auto-generated method stub
    		Intent intent = new Intent(HomeMapActivity.this, HomeListActivity.class);
    		startActivity(intent);
    		finish();
    	}
	} 
